package cn.changeforyou.web.dao.mybatis.ext.dao;

import cn.changeforyou.web.dao.mybatis.ext.accessScene.SqlProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 基础Dao方法
 * ByEntity支持传null, ByCondition绝不可以
 *
 * @author zhyu
 * @version 1.0
 * @date 2022/2/8 16:19
 */
public interface BaseDao<Entity> {

    String PRIMARY_KEY = "primaryKey";
    String CONDITION_PARAM = "condition";
    String ENTITY_PARAM = "entity";
    String DTO_PARAM = "dto";
    String LIST = "list";

    //--------------------------------------- 查询分割线  --------------------

    /**
     * 根据主键查询实体类
     *
     * @param primaryKey
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    Entity selectById(@Param(PRIMARY_KEY) Serializable primaryKey);

    /**
     * 根据实体类查询实体类
     *
     * @param entity
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    Entity selectByEntity(@Param(CONDITION_PARAM) Entity entity);

    /**
     * 根据条件类查询实体类
     *
     * @param param
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    Entity selectByCondition(@Param(CONDITION_PARAM) Object param);

    /**
     * 根据id查询视图
     *
     * @param primaryKey
     * @param clazz
     * @param <VO>
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    <VO> VO selectVOById(@Param(PRIMARY_KEY) Serializable primaryKey, Class<VO> clazz);

    /**
     * 根据实体类查询视图
     *
     * @param entity
     * @param clazz
     * @param <VO>
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    <VO> VO selectVOByEntity(@Param(CONDITION_PARAM) Entity entity, Class<VO> clazz);

    /**
     * 根据条件类查询视图
     *
     * @param param
     * @param clazz
     * @param <VO>
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    <VO> VO selectVOByCondition(@Param(CONDITION_PARAM) Object param, Class<VO> clazz);

    /**
     * 根据主键查询Map
     *
     * @param primaryKey
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    Map<String, Object> selectMapById(@Param(PRIMARY_KEY) Serializable primaryKey);

    /**
     * 根据实体类查询Map
     *
     * @param entity
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    Map<String, Object> selectMapByEntity(@Param(CONDITION_PARAM) Entity entity);

    /**
     * 根据条件类查询Map
     *
     * @param param
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    Map<String, Object> selectMapByCondition(@Param(CONDITION_PARAM) Object param);

    /**
     * 根据实体类查询实体List
     *
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    List<Entity> selectListByEntity(@Param(CONDITION_PARAM) Entity entity);

    /**
     * 根据条件查询类查询实体List
     *
     * @param param
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    List<Entity> selectListByCondition(@Param(CONDITION_PARAM) Object param);

    /**
     * 根据实体类查询视图List
     *
     * @param entity
     * @param clazz
     * @param <VO>
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    <VO> List<VO> selectVOListByEntity(@Param(CONDITION_PARAM) Entity entity, Class<VO> clazz);

    /**
     * 根据条件类查询视图List
     *
     * @param param
     * @param clazz
     * @param <VO>
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    <VO> List<VO> selectVOListByCondition(@Param(CONDITION_PARAM) Object param, Class<VO> clazz);

    /**
     * 根据实体类查询MapList
     *
     * @param entity
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    List<Map<String, Object>> selectMapsByEntity(@Param(CONDITION_PARAM) Entity entity);

    /**
     * 根据条件类查询MapList
     *
     * @param condition
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    List<Map<String, Object>> selectMapsByCondition(@Param(CONDITION_PARAM) Object condition);

    /**
     * 根据实体类查询数量
     *
     * @param entity
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    int countByEntity(@Param(CONDITION_PARAM) Entity entity);

    /**
     * 根据条件类查询数量
     *
     * @param condition
     * @return
     */
    @SelectProvider(value = SqlProvider.class, method = "dynamic")
    int countByCondition(@Param(CONDITION_PARAM) Object condition);
    //--------------------------------------- 新增分割线 --------------------

    /**
     * 插入实体
     *
     * @param entity
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int insert(Entity entity);

    /**
     * 插入实体列表
     *
     * @param entity
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int insertList(@Param(LIST) List<Entity> entity);

    /**
     * 插入dto
     *
     * @param DTO
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int insertDTO(Object DTO);

    /**
     * 插入实体列表
     *
     * @param DTO
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int insertDTOs(@Param(LIST) List<?> DTO);

    //------------------------------------ 修改分割线 --------------------

    /**
     * 修改实体类
     *
     * @param entity
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int updateEntity(Entity entity);

    /**
     * 忽视null修改实体类
     *
     * @param entity
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int updateEntityIgnoreNull(Entity entity);

    /**
     * 修改数据传输对象
     *
     * @param entity
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int updateDTO(Object entity);

    /**
     * 忽视null修改数据传输对象
     *
     * @param entity
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int updateDTOIgnoreNull(Object entity);

    /**
     * 通过条件类修改实体类
     *
     * @param entity
     * @param param
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int updateEntityByCondition(@Param(ENTITY_PARAM) Entity entity, @Param(CONDITION_PARAM) Object param);

    /**
     * 通过条件类修改dto
     *
     * @param dto
     * @param param
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int updateDTOByCondition(@Param(DTO_PARAM) Object dto, @Param(CONDITION_PARAM) Object param);

    //------------------------------------------- 删除分割线 -----------------------------

    /**
     * 删除实体
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int delete(Entity entity);

    /**
     * 删除实体
     * @return
     */
    @InsertProvider(value = SqlProvider.class, method = "dynamic")
    int deleteById(@Param(PRIMARY_KEY) Serializable primaryKey);
}